<!--
 * @Author: Lian
 * @Date: 2022-04-28 08:49:39
 * @LastEditors: Lian
 * @LastEditTime: 2022-04-28 17:56:34
 * @Description: 扫雷
-->
<template>
  <view class="content">
    <button @click="reloadGame">重新开始</button>
    <view class="checkerboard-box">
      <view class="box-row" v-for="(JItem, Jindex) in checkerboard" :key="Jindex">
        <view class="item-box" :ref="`JItem${Jindex}-${index}`" v-for="(item, index) in JItem" :key="index" @click="checkGrid([Jindex, index])"> </view>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  data () {
    return {
      checkerboard: [    // 棋盘
        [0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0],
      ],
      selectBoard: [    // 记录棋盘操作
        [0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0],
      ],
      GameState: '',   // 游戏状态 🧡win是赢了 💥lose是输了
      minesNum: 10,   // 🌑地雷数量
      selectNum: 0,    // ⭕已打开格子数量
    }
  },
  onShow: function () {
	this.initGame()
  },
  methods: {
    // 👉👉初始化游戏
    initGame () {
      let landmineList = this.createLandmine()
      this.checkerboard = this.buriedLandmines(landmineList, this.checkerboard)
      this.checkerboard = this.setSumNearMines(this.checkerboard)
    },

    // 点击格子
    checkGrid (coord) {
      if (this.GameState === '') {
        this.disperseGird(coord)
        this.isWin() && this.GameWin()
      }
    },

    // 重新开始游戏
    reloadGame () {
      uni.redirectTo({
        url: './checkMines'
      })
    },

    // 游戏失败
    GameLose () {
      this.GameState = 'lose'
      uni.showModal({
        title: '你输了',
        content: '点击确定重新开始游戏',
        success: (res) => {
          if (res.confirm) {
            this.reloadGame()
          }
        }
      })
    },

    // 游戏获胜
    GameWin () {
      this.GameState = 'win'
      uni.showModal({
        title: '恭喜你获胜了！！！',
        content: '点击确定重新开始游戏',
        success: (res) => {
          if (res.confirm) {
            this.reloadGame()
          }
        }
      })
    },

    /**
    * @description: 生成地雷位置
    * @param {num} 地雷数量
    * @param {row} 棋盘的行数
    * @param {column} 棋盘的列数
    * @return: 地雷的位置list
    */
    createLandmine (num = 10, row = 9, column = 9) {
      let landmineList = []
      while (landmineList.length < num) {
        let landmine = this.randomLandmine(row, column)
		if (!this.include(landmine, landmineList)){
			landmineList.push(landmine)
		}
      }
      return landmineList
    },
	
	/**
	* @description: 判断是否包含
	* @param {arr1} 被包含数组
	* @param {arr2} 大数组
	* @return: true false
	*/
	include(arr1, arr2) {
		let isInclude = false
		const arr1_s = arr1.toString()
		arr2.forEach((item) => {
			if (item.toString() == arr1_s) {
				isInclude = true
			}
		})
		return isInclude
	},

    /**
    * @description: 随机生成一个地雷位置
    * @param {row} 棋盘的行数
    * @param {column} 棋盘的列数
    * @return: 地雷的位置
    */
    randomLandmine (row, column) {
      const landmine = [Math.floor(Math.random() * row), Math.floor(Math.random() * column)]
      return landmine
    },

    /**
    * @description: 埋地雷
    * @param {landmineList} 地雷坐标列表
    * @param {checkerboard} 棋盘
    * @return: 埋好雷的棋盘
    */
    buriedLandmines (landmineList, checkerboard) {
      landmineList.forEach((item) => {
        checkerboard[item[0]][item[1]] = -1
      });
      return checkerboard
    },

    /**
    * @description: 获取附近格子坐标
    * @param {coord} 中心点格子坐标
    * @param {row} 棋盘的行数
    * @param {column} 棋盘的列数
    * @return: 附近的格子坐标
    */
    getNearCoord (coord, row, column) {
      const rowList = [coord[0] - 1, coord[0], coord[0] + 1]
      const columnList = [coord[1] - 1, coord[1], coord[1] + 1]
      let nearCoord = []
      for (let i in rowList) {
        for (let j in columnList) {
          (rowList[i] >= 0 && rowList[i] < row && columnList[j] >= 0 && columnList[j] < column) && nearCoord.push([rowList[i], columnList[j]])
        }
      }
      return nearCoord
    },

    /**
    * @description: 获取附近地雷数量
    * @param {nearCoord} 附近格子坐标
    * @param {checkerboard} 棋盘
    * @return: 附近地雷数量
    */
    sumNearMines (nearCoord, checkerboard) {
      let sum = 0
      for (let i in nearCoord) {
        checkerboard[nearCoord[i][0]][nearCoord[i][1]] === -1 && sum++
      }
      return sum
    },

    /**
    * @description: 显示每个格子附近的地雷数量
    * @param {checkerboard} 棋盘
    * @return: 显示每个格子附近的地雷数量的棋盘
    */
    setSumNearMines (checkerboard) {
      let newCheckboard = checkerboard
      for (let i = 0; i < checkerboard.length; i++) {
        for (let j = 0; j < checkerboard[i].length; j++) {
          if (checkerboard[i][j] != -1) {
            let nearCoord = this.getNearCoord([i, j], checkerboard[i].length, checkerboard.length)
            newCheckboard[i][j] = this.sumNearMines(nearCoord, checkerboard)
          }
        }
      }
      return newCheckboard
    },

    /**
    * @description: 打开某个格子
    * @param {coord} 格子坐标
    */
    openGrid (coord) {
      this.selectNum++
      this.selectBoard[coord[0]][coord[1]] = 1
      this.$refs[`JItem${coord[0]}-${coord[1]}`][0].$el.className = 'selected-box item-box'
      let innertext = ''
      this.checkerboard[coord[0]][coord[1]] == -1 ? innertext = '🌑' : this.checkerboard[coord[0]][coord[1]] > 0 ? innertext = this.checkerboard[coord[0]][coord[1]] : ''
      this.$refs[`JItem${coord[0]}-${coord[1]}`][0].$el.innerText = innertext
      // 地雷爆炸效果
      if (innertext == '🌑') {
        setTimeout(() => {
          this.$refs[`JItem${coord[0]}-${coord[1]}`][0].$el.innerText = '💥'
        }, 100)
      }
    },

    /**
    * @description: 获取上下左右格子坐标
    * @param {coord} 中心点格子坐标
    * @param {row} 棋盘的行数
    * @param {column} 棋盘的列数
    * @return: 附近的格子坐标
    */
    getNearGrid (coord, row, column) {
      const nearCoord = [[coord[0] - 1, coord[1]], [coord[0], coord[1] - 1], [coord[0], coord[1] + 1], [coord[0] + 1, coord[1]]]
      let newNearCoord = []
      for (let i in nearCoord) {
        if (nearCoord[i][0] >= 0 && nearCoord[i][0] < row && nearCoord[i][1] >= 0 && nearCoord[i][1] < column) {
          newNearCoord.push(nearCoord[i])
        }
      }
      return newNearCoord
    },

    /**
    * @description: 点击散开效果
    * @param {coord} 中心点格子坐标
    */
    disperseGird (coord) {
      if (this.selectBoard[coord[0]][coord[1]] == 0) {
        this.openGrid(coord)
        if (this.checkerboard[coord[0]][coord[1]] == -1) {
          this.GameLose()
        }
        if (this.checkerboard[coord[0]][coord[1]] == 0) {
          let nearCoord = this.getNearGrid(coord, this.checkerboard[0].length, this.checkerboard.length)
          for (let i in nearCoord) {
            this.disperseGird(nearCoord[i])
          }
        }
      }
    },

    /**
    * @description: 判断是否获胜
    */
    isWin () {
      let isWin = false
      const num = (this.checkerboard[0].length * this.checkerboard.length) - this.selectNum
      num <= this.minesNum && (isWin = true)
      return isWin
    }
  }
}
</script>

<style lang="scss" scoped>
.box-row {
  display: flex;
  text-align: center;
  .item-box {
    width: 11%;
    height: 11vw;
    line-height: 11vw;
    border: 1px solid rgb(230, 230, 230);
    background-color: rgb(82, 177, 255);
  }
  .selected-box {
    background-color: #fff;
    // border: 1px solid rgb(163, 163, 163);
    // box-sizing: border-box;
  }
}
</style>